﻿//////////////////////////////////////////////////
//                Thaumaturge.cs                //
//         Part of RebornCo by kaihaider        //
//////////////////////////////////////////////////

using System;
using System.Threading.Tasks;
using ff14bot;
using ff14bot.Enums;
using ff14bot.Objects;
using RebornCo.Settings;
using RebornCo.Helpers;
using TreeSharp;

namespace RebornCo.Rotations
{
    public class Thaumaturge : RebornCoRoutine
    {
        public override void OnInitialize()
        {
            WantHealing = false;
            WindowSettings = new ThaumaturgeSetting();
        }
        public static ThaumaturgeSetting ThaumaturgeSettings
        {
            get { return WindowSettings as ThaumaturgeSetting; }
        }
        public sealed override ClassJobType[] Class
        {
            get
            {
                return new [] 
                { 
                   ClassJobType.Thaumaturge, ClassJobType.BlackMage
                };
            }
        }
        [Behavior(BehaviorType.PreCombatBuffs)]
        public Composite ThaumaturgeCreateBasicPreCombatBuffs()
        {
            return new ActionRunCoroutine(ctx => ThaumaturgeBuildPreCombatBuffs());
        }
        public static async Task<bool> ThaumaturgeBuildPreCombatBuffs()
        {
            if (!IsValid()) return false;
            if (Resting)
            {
                if (!Core.Player.IsCasting && await Spell.Cast("Cure", Core.Player, Core.Player.CurrentHealthPercent < 70 && Core.Player.CurrentHealthPercent < Core.Player.CurrentManaPercent)) return true;
                if (!Core.Player.IsCasting && await Spell.Cast("Physick", Core.Player, Core.Player.CurrentHealthPercent < 70 && Core.Player.CurrentHealthPercent < Core.Player.CurrentManaPercent)) return true;

                if (Core.Player.CurrentManaPercent < ThaumaturgeSettings.RestEnergyDone)
                {
                    if (Core.Player.HasAura("Astral Fire") || Core.Player.HasAura("Astral Fire II") || Core.Player.HasAura("Astral Fire III"))
                        await Spell.Cast("Transpose", Core.Player, true);
                    if(Core.Player.CurrentHealthPercent > ThaumaturgeSettings.RestHealthDone 
                        && !(Core.Player.HasAura("Astral Fire") || Core.Player.HasAura("Astral Fire II") || Core.Player.HasAura("Astral Fire III")
                        || Core.Player.HasAura("Umbral Ice") || Core.Player.HasAura("Umbral Ice II") || Core.Player.HasAura("Umbral Ice III") )) 
                        Resting = false;
                }

                return false;
            }
            if (await Spell.BuffParty("Protect")) return true;
            if (await Spell.BuffParty("Stoneskin")) return true;
            return await CombatCompanion();
        }

        [Behavior(BehaviorType.Rest)]
        public Composite ThaumaturgeCreateBasicRest()
        {
            return new PrioritySelector(
        //        new Decorator(ctx => Resting 
         //           && (Core.Player.HasAura("Astral Fire") || Core.Player.HasAura("Astral Fire II") || Core.Player.HasAura("Astral Fire III")),
        //            new ActionRunCoroutine(ctx => Spell.Cast("Transpose", Core.Player, true))),
                new ActionRunCoroutine(ctx => DefaultRestBehavior(Core.Player.CurrentManaPercent))); 
        }


        [Behavior(BehaviorType.CombatBuffs)]
        public Composite ThaumaturgeCreateBasicCombatBuffs()
        {
            return new ActionRunCoroutine(ctx => ThaumaturgeBuildCombatBuffs()); 
        }
        public static async Task<bool> ThaumaturgeBuildCombatBuffs()
        {//kite Lethargy
            //Apocatastasis low life party memeber
            //Aetherial Manipulation - teleport to party
            //swiftcast when?
            //sleep add
            //Transpose - swaps fire/ice buff
            ShouldPulse = true;
            if (await Spell.Cast("Cure", Core.Player, Core.Player.CurrentHealthPercent < 40)) return true;
            if (await Spell.Cast("Physick", Core.Player, Core.Player.CurrentHealthPercent < 40)) return true;
            if (await Spell.ConfirmedCast("Transpose", Core.Player, Core.Player.HasAura("Umbral Ice III")
                                                                    && Core.Player.HasAura("Firestarter") &&
                                                                    Core.Player.CurrentManaPercent > 90, true))return true;
            if (await Spell.ConfirmedCast("Transpose", Core.Player, Core.Player.ClassLevel < 38
                                                                    && FireAura &&
                                                                    Core.Player.CurrentManaPercent <
                                                                    ThaumaturgeSettings.DumpMana, true)) return true;
            if (Spell.GcdTime < ThaumaturgeSettings.NoneGcdWindowEnd) return false;

            if (!Spell.UsedNoneGcd && await Spell.CastLock("Manawall", Core.Player, Core.Player.CurrentHealthPercent < ThaumaturgeSettings.Manawall))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Manaward", Core.Player, Core.Player.CurrentHealthPercent < ThaumaturgeSettings.Manaward))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
                
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Surecast", Core.Player, ThaumaturgeSettings.Surecast
                && (Core.Player.CurrentTarget as BattleCharacter) !=null && (Core.Player.CurrentTarget as BattleCharacter).CurrentTargetId == Core.Player.ObjectId 
                && Core.Player.CurrentTarget.Location.Distance2D(Core.Player.Location) < Movement.ObjectMeleeRange(Core.Player.CurrentTarget)))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Convert", Core.Player, !ThaumaturgeSettings.OnlyConvertFlare &&Core.Player.CurrentHealthPercent > ThaumaturgeSettings.ConvertHp
                && Core.Player.CurrentManaPercent < ThaumaturgeSettings.ConvertMp))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Invigorate", Core.Player, Core.Player.CurrentTPPercent < 50))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Eye for an Eye", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Foresight", Core.Player, Core.Player.CurrentHealthPercent < 80))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Blood for Blood", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Internal Release", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (WindowSettings.CooldownsUsable && Spell.Potion != null && Spell.Potion.IsValid
                && Spell.Potion.CanUse(Core.Player) && Spell.Potion.Name.Equals(WindowSettings.PotionName))
            {
                Spell.Potion.UseItem(Core.Player);
                if (WindowSettings.PotionForce) Spell.UsedNoneGcd = true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Quelling Strikes", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Hawk's Eye", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Bloodbath", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Raging Strikes", Core.Player, Core.Player.CurrentManaPercent > 40))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Keen Flurry", Core.Player, Core.Player.CurrentHealthPercent < 80))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Convalescence", Core.Player, Core.Player.CurrentHealthPercent < 70))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Second Wind", Core.Player, Core.Player.CurrentHealthPercent < 40))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Awareness", Core.Player, Core.Player.CurrentHealthPercent < 30))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Featherfoot", Core.Player, Core.Player.Distance2D() < 5))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            return false;
        }


        [Behavior(BehaviorType.Pull)]
        public Composite ThaumaturgeCreateBasicPull()
        {
            return new ActionRunCoroutine(ctx => ThaumaturgeBuildPullBehavior()); 
        }
        public static async Task<bool> ThaumaturgeBuildPullBehavior()
        {
            if (Core.Player.CurrentTarget != null && !Core.Player.CurrentTarget.CanAttack || !IsValid()) return false;
            ShouldPulse = true;
            await Target.EnsureValidTarget();
            if (await Movement.PullMove(Core.Player.CurrentTarget)) return true;

            if (Core.Player.HasAura("Astral Fire") || Core.Player.HasAura("Astral Fire II") ||
                Core.Player.HasAura("Astral Fire III"))
                FireAura = true;
            else FireAura = false;
            if (Core.Player.HasAura("Umbral Ice") || Core.Player.HasAura("Umbral Ice II") ||
                Core.Player.HasAura("Umbral Ice III"))
                IceAura = true;
            else IceAura = false;
            await CheckAuraGuess();
            if (Core.Player.CurrentManaPercent < ThaumaturgeSettings.DumpMana || !IceAura && !FireAura && Core.Player.ClassLevel < 34
                || !Core.Player.CurrentTarget.HasAura("Thunder", true, ThaumaturgeSettings.ThunderClip))
            {
                if (Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent > ThaumaturgeSettings.MinDotHp
                    && IceAura && !FireAura && !Core.Player.CurrentTarget.HasAura("Thunder", true,
                    Extensions.DoubleCastPreventionDict.Contains(Core.Player.CurrentTarget, "Blizzard III") ? ThaumaturgeSettings.ThunderClip + 7000 : ThaumaturgeSettings.ThunderClip))
                {
                    if (Extensions.DoubleCastPreventionDict.Contains(Core.Player.CurrentTarget, "Thunder III")) Extensions.UpdateDoubleCastDictSpecific("Thunder II", Core.Player.CurrentTarget);
                    if (Extensions.DoubleCastPreventionDict.Contains(Core.Player.CurrentTarget, "Thunder II")) Extensions.UpdateDoubleCastDictSpecific("Thunder III", Core.Player.CurrentTarget);
                    if (!Spell.Gcd && await Spell.CastLock("Thunder III", Core.Player.CurrentTarget)) return true;
                    if (!Spell.Gcd && await Spell.CastLock("Thunder II", Core.Player.CurrentTarget)) return true;
                    //if (!Spell.Gcd && await Spell.CastLock("Thunder", Core.Player.CurrentTarget)) return true; 
                }
                if (!Spell.Gcd && !AIce && await Spell.ConfirmedCast("Blizzard III", Core.Player.CurrentTarget, FireAura
                    && Core.Player.CurrentManaPercent < ThaumaturgeSettings.DumpMana
                    // ReSharper disable ConditionIsAlwaysTrueOrFalse
                    && (!Extensions.DoubleCastPreventionDict.Contains(null, "Swiftcast")
                    && (!ThaumaturgeSettings.SingleTargetFlare || !ff14bot.Managers.Actionmanager.CurrentActions.ContainsKey("Convert")
                        || Spell.GetSpellData("Convert").Cooldown.TotalSeconds > 60)
                    && await Spell.ConfirmedCast("Swiftcast", Core.Player) || true)))
                // ReSharper restore ConditionIsAlwaysTrueOrFalse, true)) return true;
                {
                    Extensions.UpdateDoubleCastDictSpecific("Blizzard III", null, 5);
                    AuraCountdown = DateTime.UtcNow.TimeOfDay + TimeSpan.FromSeconds(1.5);
                    AIce = true;
                    AFire = false;
                    return true;
                }
                if (!Spell.Gcd && await Spell.Cast("Blizzard", Core.Player.CurrentTarget, Core.Player.ClassLevel == 1
                   || Core.Player.CurrentManaPercent < ThaumaturgeSettings.DumpMana
                   && (IceAura || !IceAura && !FireAura))) //!Extensions.DoubleCastPreventionDict.Contains(null, "Transpose")
                {
                    AuraCountdown = DateTime.UtcNow.TimeOfDay + TimeSpan.FromSeconds(1.5);
                    AIce = true;
                    AFire = false;
                    return true;
                }
            }
            if (!Spell.Gcd && !FireAura && Core.Player.ClassLevel >= 34 && Core.Player.CurrentManaPercent > ThaumaturgeSettings.DumpMana + 10) //!Core.Player.HasAura("Astral Fire II"))))
            {
                await Spell.Cast("Fire III", Core.Player.CurrentTarget, true, false, false, true);
                if (await Buddy.Coroutines.Coroutine.Wait(500 + ThaumaturgeSettings.SpellQueue, () => Core.Player.IsCasting && Core.Player.CastingSpellId == 152))
                {
                    AuraCountdown = DateTime.UtcNow.TimeOfDay + TimeSpan.FromSeconds(Core.Player.SpellCastInfo.RemainingCastTime.TotalSeconds + 1.5);
                    AIce = false;
                    AFire = true;
                    FireAura = true;
                }
                return true;
            }
            if (!Spell.Gcd && await Spell.Cast("Fire", Core.Player.CurrentTarget, Core.Player.CurrentManaPercent > ThaumaturgeSettings.DumpMana
                && (Core.Player.ClassLevel <= 34 || FireAura && !Extensions.DoubleCastPreventionDict.Contains(Core.Player.CurrentTarget, "Blizzard III")
         ))) return true;

            return false;

        }

        [Behavior(BehaviorType.Combat)]
        public Composite ThaumaturgeCreateBasicCombat()
        {
            return new ActionRunCoroutine(ctx => ThaumaturgeBuildBasicCombat()); 
        }
        public static async Task<bool> ThaumaturgeBuildBasicCombat()
        {
            await Target.EnsureValidTarget();
            await Movement.MoveToTarget();
            if (Core.Player.CurrentTarget != null && ff14bot.Managers.MovementManager.IsMoving
                && !(Core.Player.CurrentTarget.InLineOfSight() && Movement.IsInSafeRange(Core.Player.CurrentTarget))) return true;

            if (Core.Player.HasAura("Astral Fire") || Core.Player.HasAura("Astral Fire II") ||
                Core.Player.HasAura("Astral Fire III"))
                FireAura = true;
            else FireAura = false;
            if (Core.Player.HasAura("Umbral Ice") || Core.Player.HasAura("Umbral Ice II") ||
                Core.Player.HasAura("Umbral Ice III"))
                IceAura = true;
            else IceAura = false;
            await CheckAuraGuess();
            //add aoe flare
            if (!Spell.Gcd && ThaumaturgeSettings.SingleTargetFlare && await Spell.CastLock("Flare", Core.Player.CurrentTarget, Core.Player.CurrentManaPercent < ThaumaturgeSettings.DumpMana
                // ReSharper disable ConditionIsAlwaysTrueOrFalse
                && (!Extensions.DoubleCastPreventionDict.Contains(null, "Swiftcast")
                && ff14bot.Managers.Actionmanager.CurrentActions.ContainsKey("Convert")
                && Spell.GetSpellData("Convert").Cooldown.TotalMilliseconds < ThaumaturgeSettings.SpellQueue+2500
                && await Spell.ConfirmedCast("Swiftcast", Core.Player) || true))) return true;
            // ReSharper restore ConditionIsAlwaysTrueOrFalse

            if (!Spell.Gcd && !Core.Player.HasAura("Swiftcast"))
            {
                if (Core.Player.HasAura("Thundercloud"))
                {
                    if (Core.Player.ClassLevel < 46 && await Spell.CastLock("Thunder II", Core.Player.CurrentTarget)) return true;
                    return await Spell.Cast("Thunder III", Core.Player.CurrentTarget);

                }
                if (!Extensions.DoubleCastPreventionDict.Contains(Core.Player.CurrentTarget, "Fire III") && Core.Player.HasAura("Firestarter"))//last spell not bliz III
                {
                    return await Spell.CastLock("Fire III", Core.Player.CurrentTarget, true);//!IceAura || IceAura && last spell Transpose
                }
            }

            if (await Spell.CastLock("Scathe", Core.Player.CurrentTarget, ff14bot.Managers.MovementManager.IsMoving)) return true;
            //if (!Spell.Gcd && await Spell.Cast("Blizzard II", Core.Player, ThaumaturgeSettings.Aoe)) return true;
            if (Core.Player.CurrentManaPercent < ThaumaturgeSettings.DumpMana || !IceAura && !FireAura && Core.Player.ClassLevel < 34) 
            {
                if (Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent > ThaumaturgeSettings.MinDotHp
                    && IceAura && !FireAura && !Core.Player.CurrentTarget.HasAura("Thunder", true,
                    Extensions.DoubleCastPreventionDict.Contains(null, "Blizzard III") ? ThaumaturgeSettings.ThunderClip + ThaumaturgeSettings.AddThunderClipAfterB3 : ThaumaturgeSettings.ThunderClip))
                {
                    if (Extensions.DoubleCastPreventionDict.Contains(Core.Player.CurrentTarget, "Thunder III")) Extensions.UpdateDoubleCastDictSpecific("Thunder II", Core.Player.CurrentTarget);
                    if (Extensions.DoubleCastPreventionDict.Contains(Core.Player.CurrentTarget, "Thunder II")) Extensions.UpdateDoubleCastDictSpecific("Thunder III", Core.Player.CurrentTarget);
                    if (!Spell.Gcd && await Spell.CastLock("Thunder III", Core.Player.CurrentTarget)) return true;//Scathe?
                    if (!Spell.Gcd && await Spell.CastLock("Thunder II", Core.Player.CurrentTarget)) return true;
                    //if (!Spell.Gcd && await Spell.CastLock("Thunder", Core.Player.CurrentTarget)) return true; 
                }
                if (!Spell.Gcd && !AIce && await Spell.ConfirmedCast("Blizzard III", Core.Player.CurrentTarget, FireAura
                    && Core.Player.CurrentManaPercent < ThaumaturgeSettings.DumpMana
// ReSharper disable ConditionIsAlwaysTrueOrFalse
                    && (!Extensions.DoubleCastPreventionDict.Contains(null, "Swiftcast")
                    && (!ThaumaturgeSettings.SingleTargetFlare  || !ff14bot.Managers.Actionmanager.CurrentActions.ContainsKey("Convert") 
                        || Spell.GetSpellData("Convert").Cooldown.TotalSeconds > 60)
                    && await Spell.ConfirmedCast("Swiftcast", Core.Player) || true)))
                // ReSharper restore ConditionIsAlwaysTrueOrFalse, true)) return true;
                {
                    Extensions.UpdateDoubleCastDictSpecific("Blizzard III", null, 5);
                    AuraCountdown = DateTime.UtcNow.TimeOfDay + TimeSpan.FromSeconds(1.5);
                    AIce = true;
                    AFire = false;
                    return true;
                }
                if (!Spell.Gcd && await Spell.Cast("Blizzard", Core.Player.CurrentTarget, Core.Player.ClassLevel == 1 
                   || Core.Player.CurrentManaPercent < ThaumaturgeSettings.DumpMana 
                   && (IceAura || !IceAura && !FireAura))) //!Extensions.DoubleCastPreventionDict.Contains(null, "Transpose")
                {
                    AuraCountdown = DateTime.UtcNow.TimeOfDay + TimeSpan.FromSeconds(1.5);
                    AIce = true;
                    AFire = false;
                    return true;
                }
            }
          
            //if (!Spell.Gcd && await Spell.Cast("Thunder", Core.Player.CurrentTarget)) return true; // last spell blizzard III
            
            //swift cast for fire if convert down and fire aura

            if (!FireAura && Core.Player.ClassLevel >= 34 && Core.Player.CurrentManaPercent > ThaumaturgeSettings.DumpMana + 10) //!Core.Player.HasAura("Astral Fire II"))))
            {
                await Spell.Cast("Fire III", Core.Player.CurrentTarget, true, false, false, true);
             //   && (Core.Player.ClassLevel >= 40 && !FireAura) //Core.Player.HasAura("Astral Fire III"))
               // || (Core.Player.ClassLevel >= 34 && Core.Player.ClassLevel < 40 && !FireAura), false, true, true)

                //Extensions.UpdateDoubleCastDictSpecific("Fire III", null, 5);
                return true;
            }
            
            //if (!Spell.Gcd && await Spell.Cast("Fire II", Core.Player.CurrentTarget,ThaumaturgeSettings.Aoe)) return true; aoe
            //Core.Player.ClassLevel < 38 && 
            if (await Spell.Cast("Fire", Core.Player.CurrentTarget, Core.Player.CurrentManaPercent > ThaumaturgeSettings.DumpMana
                && (Core.Player.ClassLevel < 34 || FireAura && !Extensions.DoubleCastPreventionDict.Contains(Core.Player.CurrentTarget, "Blizzard III") || Extensions.DoubleCastPreventionDict.Contains(Core.Player.CurrentTarget, "Fire III"))
// ReSharper disable ConditionIsAlwaysTrueOrFalse
                && (Core.Player.ClassLevel < 38 && ff14bot.Managers.MovementManager.IsMoving && !Extensions.DoubleCastPreventionDict.Contains(null, "Swiftcast")
                && (!ThaumaturgeSettings.SingleTargetFlare  || !ff14bot.Managers.Actionmanager.CurrentActions.ContainsKey("Convert") 
                    || Spell.GetSpellData("Convert").Cooldown.TotalSeconds > 60)
                && await Spell.ConfirmedCast("Swiftcast", Core.Player) || true)))
// ReSharper restore ConditionIsAlwaysTrueOrFalse
            {
               // AuraCountdown = DateTime.UtcNow.TimeOfDay + TimeSpan.FromSeconds(1.5); AIce = false; AFire = true;
                return true;
            }


            if (Spell.GcdTime < ThaumaturgeSettings.NoneGcdWindowEnd) return false;

            if (!Spell.UsedNoneGcd && await Spell.CastLock("Mercy Stroke", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent < 20))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }

            return false;
        }

#pragma warning disable 1998
        public static async Task CheckAuraGuess()
#pragma warning restore 1998
        {
            if (Core.Player.IsCasting && (Core.Player.CastingSpellId == 152 || Core.Player.CastingSpellId == 141))
            {
                AuraCountdown = DateTime.UtcNow.TimeOfDay + TimeSpan.FromSeconds(Core.Player.SpellCastInfo.RemainingCastTime.TotalSeconds+1.5);
                AIce = false;
                AFire = true;
                FireAura = true;
                return;
            }
            if (AuraCountdown > DateTime.UtcNow.TimeOfDay)
            {
                if(AFire)
                    FireAura = AFire;
                if(AIce)
                    IceAura = AIce;
                return;
            }
            AFire = false;
            AIce = false;
        }

        public static TimeSpan AuraCountdown;
        public static bool FireAura, IceAura, AFire, AIce;

    }
}
